home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / turbwind.arc / TURBWIND.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1985-10-14  |  10.3 KB  |  280 lines

  1. {$I-,R-,V-,U-,K-}
  2. program Turbo_Timer_Window;
  3.  
  4. { - this is a stay-resident program providing full-screen windows
  5.     accessed by printing commands on the screen. Date and running Clock
  6.     as well as addl.info is placed directly into the screen memory.
  7.   - once installed, you print a command (nS-save window N, nL-load window N)
  8.     at the position specified by <Window_Cmd_Pos> and the program will
  9.     save or load the desired screen next time the internal clock ticks.
  10.     (18.2 times/sec)
  11.   - info/date/time are updated every <Ticks_in_between> times the clock-
  12.     interrupt occours.
  13.     (with in_between=6 the effective clockspeed is .957% or 4.56MHz)
  14.   - syntax :
  15.       nc  where n is the window number 0..screen_limit  and
  16.                 c is the command, either S or L
  17.        the command has to be printed at character position <Window_Cmd_Pos>
  18.  
  19.   - note: date is not updated
  20.   - note: need facility (new window cmd) to change/set Info_Str,
  21.           to enable/disable screen update, to enable/disable routine.
  22. }
  23.     Type  {basic Types}
  24.      Register_Set =Record Case Integer Of
  25.        1: (AX,BX,CX,DX,BP,SI,DI,DS,ES,Flags: Integer);
  26.        2: (AL,AH,BL,BH,CL,CH,DL,DH: Byte); End;
  27.      Any_String =String[80];
  28.      String2 =String[2];
  29.      String3 =String[3];
  30.      Memory_Address =record S,O : integer ; end;
  31.      DoW =(Sun,Mon,Tue,Wed,Thu,Fri,Sat);
  32.      Date_Type =Record Month,Day,Year: Byte; DayOfWeek: DOW; End;
  33.     Const {all typed constants are Vars for IRQ sub}
  34.      Tick_Count :Integer =0;
  35.      regs :register_set =(ax:0;bx:0;cx:0;dx:0;bp:0;si:0;di:0;ds:0;es:0;flags:0);
  36.      saveds :integer =0;
  37.      Screen_Ptr :String3 ='abc';
  38.      Buffer_Ptr :String3 ='def';
  39.      Window_Cmd :char =' ';
  40.      Window_No :integer = 0;
  41.      Date_Str :Any_String= '';
  42.      Hours :integer = 0;
  43.      Minut :integer = 0;
  44.      Secon :integer = 0;
  45.      i :integer = 0;
  46.     Const
  47.      Info_Str='Turbo_Timer_Window V1.0 Active';
  48.      Ticks_in_between =6;{ticks between calls of our int 6=4*/sec}
  49.      Low_Window=$30;     {code letter(='0') for first window}
  50.      High_Window=$33;    {code letter(='3') for last window  4 screens}
  51.      Screen_Size=2000;   {80*25*2(Attr:Char) =4kb/screen}
  52.     Type
  53.      Single_Screen =array[1..Screen_Size] of Integer;
  54.      Screen_Buffer_Type =array[Low_Window..High_Window] of Single_Screen;
  55.     Var
  56.      Timer_Low :Integer absolute $0040:$006C;   { BIOS dependent }
  57.      Timer_High :Integer absolute $0040:$006E;
  58.      Screen :^Single_Screen absolute Screen_Ptr;
  59.      Memory :^Screen_Buffer_Type absolute Buffer_Ptr;
  60.     Const {screen Positions}
  61.      Date_End =70;
  62.      Window_Cmd_Pos = 71;
  63.      Time_Pos =73;
  64.     Const {char/attr defi}
  65.      Blk = $0000;
  66.      Low = $0700;
  67.      Hig = $0F00;
  68.      Low_Spc = $0720;      { ' ' low intensity }
  69.      Zero = $0F30;      { '0' low intensity }
  70.     Const {*bios calls*}
  71.      Video_IO =$10;
  72.      Video_Read_Mode =$0F;
  73.      Timer_Int =$08;
  74.      Terminate_Resident =$27;
  75.      User_Int =$68;  { range from $60..$67, unused int range $68..$7f }
  76.     Const {*function calls*}
  77.      dos_Function =$21;
  78.      dos_Get_Date =$2A;
  79.      dos_Get_Time =$2C;
  80.       Ticks_Sec =18;
  81.       Ticks_Min =546; {1092;}  { actually 1092, program does div 2 before}
  82.       Ticks_Hour =65543.0; { $10007}
  83.      dos_Set_Vector =$25; {interrupt type AX set to DS:DX}
  84.      dos_Get_Vector =$35; {addr interrupt AX in ES:BX}
  85.  
  86.   Procedure Turbo_Timer_Tick;
  87.    begin
  88.     {$Iregsave.inc}              {save regs}
  89.     intr(User_Int,Regs);          {exec old irq}
  90.     if Tick_Count =0    { every ticks_in_between turns date/time upd}
  91.     then begin
  92.       screen^[1]:=$0f6d; { put mAx }
  93.       screen^[2]:=$0f41;
  94.       screen^[3]:=$0f78;
  95.       for i:= 4 to Date_End do screen^[i]:=Hig+ord(Date_Str[i]); {Put Info,Date}
  96.       Hours:=Timer_High and $FF;     { prepare Time }
  97.       i:=Timer_Low;
  98.       Minut:=(i and $7fff)div 2;
  99.       if i<0 then i:=(Minut or $4000) else i:=minut;
  100.       Minut:=i div Ticks_Min; { ticks_Min is only half of actual}
  101.       Secon:=i mod Ticks_Min div Ticks_Sec; { kill secs for speed}
  102.       screen^[time_pos+0]:=Zero+Hours Div 10; { put Time }
  103.       screen^[time_pos+1]:=Zero+Hours Mod 10;
  104.       screen^[time_pos+2]:=$8f3a;
  105.       screen^[time_pos+3]:=Zero+Minut Div 10;
  106.       screen^[time_pos+4]:=Zero+Minut Mod 10;
  107.       screen^[time_pos+5]:=$8f3a;
  108.       screen^[time_pos+6]:=Zero+Secon Div 10;
  109.       screen^[time_pos+7]:=Zero+Secon Mod 10;
  110. {      for i:= 81 to 160 do screen^[i]:=$0FCD; } { line of '═' }
  111.       Tick_Count:=Ticks_in_between;
  112.       end
  113.     else Tick_Count:=Tick_Count-1;
  114.     {get Window #}
  115.     if Screen^[Window_Cmd_Pos]<>Blk
  116.      then begin
  117.            Window_No:=Lo(Screen^[Window_Cmd_Pos]);
  118.            if Window_No<=High_Window
  119.             then if Window_No>=Low_Window
  120.                   then begin
  121.                         {get command !ch}
  122.                         Window_Cmd:=chr(lo(screen^[Window_Cmd_Pos+1]) and $DF );
  123.                         {erase screen&command}
  124.                         screen^[Window_Cmd_Pos]:=Blk;
  125.                         screen^[Window_Cmd_Pos+1]:=Blk;
  126.                         case Window_Cmd of
  127.                          'L': for I:= 1 to screen_size
  128.                                do screen^[I]:=memory^[Window_No,I];
  129.                          'S': begin
  130.                                I:= 2;
  131.                                while i<=Screen_Size do begin
  132.                                 memory^[Window_No,I]:=screen^[I];
  133.                                 i:=i+2; end;
  134.                                I:= I-1;
  135.                                while i>=1 do begin
  136.                                 memory^[Window_No,I]:=screen^[I];
  137.                                 i:=i-2; end;
  138.                               end;
  139.                          else {restore Window Number}
  140.                           screen^[Window_Cmd_Pos]:=Hig+Window_No;
  141.                         end; {case}
  142.                        end;{if}
  143.           end;{if}
  144.     {$iregrstor.inc}             {restore registers}
  145.     inline($CF);                 {IRET and off we go}
  146.    end;
  147.  
  148.   Const Mark_Buffer_Begin :Byte =$00;
  149.    {remainder of progr only required for setup}
  150.  
  151.     Const
  152.      DayName: Array [DOW] Of String[3]=
  153.      ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  154.      MonName: Array [1..12] Of String[3]=
  155.      ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  156.     Var
  157.      Date_Var :Date_Type;
  158.      Dummy :Any_String;
  159.      Org_Timer_Tick :memory_address;
  160.      r :Register_Set;
  161.     Procedure Get_Date;
  162.      Begin
  163.       With R,Date_Var Do Begin
  164.        AH:=dos_Get_Date; Intr(dos_Function,R);
  165.        Month:=DH;Day:=DL;Year:=CX-1900;DayOfWeek:=DOW(AL);
  166.        End;
  167.      End;
  168.     Procedure Get_Vector (intr_number:integer; var segment,offset:integer);
  169.      begin {get the address that was there}
  170.       with r do begin
  171.        ah:=dos_Get_Vector;
  172.        al:=intr_number;
  173.        Intr(dos_Function,r);
  174.        segment:=es;
  175.        offset:=bx;
  176.        end;
  177.      end;
  178.     Procedure Set_Vector (intr_number,segment,offset:integer);
  179.      begin
  180.       with r do begin
  181.        ah:=dos_Set_Vector;
  182.        al:=intr_number;
  183.        ds:=segment;
  184.        dx:=offset;
  185.        end;
  186.       Intr(dos_Function,r);
  187.      end;
  188.     Function V2(I:Integer):String2;
  189.      Begin
  190.       V2:=Chr(48+I Div 10)+Chr(48+I Mod 10);
  191.      End;
  192.   procedure prepare_interrupt;
  193.    begin
  194.     saveds:=Dseg; {save the data segment local}
  195.     r.ah:=Video_Read_Mode; INTR(Video_IO,r); {determine video adapter}
  196.     if r.al=7 {mono}
  197.      then screen:=ptr($B000,0) else screen:=ptr($B800,0); {color}
  198.     Memory:=Addr(Mark_Buffer_Begin); {set pointer to buffer}
  199.     Get_Date;
  200.     With Date_Var do
  201.      Date_Str:= DayName[DayOfWeek]+', '+MonName[Month]+' '+V2(Day)+', 19'+V2(Year);
  202.     Date_Str:=Info_Str+'  '+Date_Str;
  203.     while Date_Str[0]<chr(Date_End) do Date_Str:=' '+Date_Str; {shift right}
  204.    end;
  205.  
  206.     Type Hex_Array = array[0..15] of Char;
  207.          String5 = String[5];
  208.     Const Hex_Digit :Hex_Array = '0123456789ABCDEF';
  209.     Function Hex(V:integer):String5;
  210.      var h:String5;
  211.      begin
  212.       h:='$0000';
  213.       for i:= 4 downto 1
  214.        do begin
  215.            h[i+1]:=hex_Digit[v and $000F];
  216.            v:=v div $10;
  217.           end;
  218.       Hex:=h;
  219.      end;
  220.   procedure install_interrupt;
  221.    begin
  222.     Get_Vector ( Timer_Int, Org_Timer_Tick.s, Org_Timer_Tick.o );
  223.     Set_Vector ( User_Int, Org_Timer_Tick.s, Org_Timer_Tick.o );
  224.     Set_Vector ( Timer_Int, seg(regs), ofs(Turbo_Timer_Tick) );
  225.     {make resident. contain all. incl stack}
  226.     r.dx:=$2+ofs(Memory^[High_Window,Screen_Size])+$400{40para stack};
  227.     writeln( #10,#10,'to install ',hex(r.dx),'  (',r.dx,') bytes hit return,  hit * to cancel');
  228.     readln(Dummy);if Dummy<>'*' then Intr(Terminate_Resident,r);
  229.     Set_Vector ( Timer_Int, Org_Timer_Tick.s, Org_Timer_Tick.o );
  230.     Set_Vector ( User_Int, 0,0 );
  231.     writeln('unlinked.');
  232.    end;
  233.  
  234.   begin
  235.    prepare_interrupt;
  236.    install_interrupt;
  237.   end.
  238.  
  239.  
  240.  
  241.   NOTE to patch the initial turbo clear screen.
  242.         DEBUG thisone.com       :note that debug offsets $100
  243.         E 02FC <return> 90 <space> 90 <return>
  244.         W <return>
  245.         Q <return>
  246.  
  247.   NOTE to compile this program,
  248.         set MinDymMem I to 12 paragraphs,
  249.         set MaxDymMem A to 40 paragraphs.
  250.        when EBL available, use following Batch file:
  251.        .
  252.        bat begstack
  253.        turbo
  254.        YOCI12
  255.        A40
  256.        q
  257.        end
  258.        .
  259.  
  260.   NOTE SideKick may screw up (when popped up during? save/load)
  261.    no other hangups found on my system. runs with spooler,VD,Network
  262.    !! but no warranty can be given that program is error free !!
  263.    i bet it isn't although i don't know of anything.
  264.  
  265.   NOTE give credit to the guy that wrote LASTCOM.pas for his demo of
  266.    a resident turbo program and to borland's bella lubkin for INT24.pas
  267.    both put out excellent programs which taught me a good deal about
  268.    bios/dos programing.
  269.  
  270.   NOTE written by Michael Ax (718) 278-6079, trying to make dbase3
  271.    a little bit more usefull.
  272.  
  273.   NOTE if you use this program, i'm sure you will change it too. please
  274.    let me know what you did and how, maybe our ideas match. also, if
  275.    you take it to assembler before i do, download a copy of it to
  276.    a board where you see my name on or give me a call.
  277.  
  278.  
  279.   7/24/85 V1.0  ...let the force be with you
  280.